import { Injectable } from '@angular/core';
import { Http, Headers } from "@angular/http";
import { Observable, Subject } from "rxjs/Rx";
import { TagData } from "../../entity/tag-data.model";
import { DatePipe } from "@angular/common";
import { AppConfig } from "../../config";
import { IHistory } from "./ihistory.interface";
import { FaultData } from "./fault-data";
import { ApplicationService } from "../../service/application.service";
import { InterceptorService } from '../../service/interceptor/interceptor-service';
@Injectable()
export class HistoryService implements IHistory {
    /**
     * 时间格式化字符串
     * 
     * @private
     * @type {string}
     * @memberof HistoryService
     */
    private fomat: string = "yyyy-MM-dd HH:mm:ss";
    private readonly param = "historys";
    private get url(): string {
        return `${AppConfig.APP_RESTFUL}/${this.param}`;
    }

    private timers: any[] = [];
    /**
  * 主题对象数组
  * 
  * @private
  * @type {Subject<any>[]}
  * @memberof IMPushService
  */
    private subjectMap: Subject<any>[] = [];
    constructor(
        private http: InterceptorService,
        // private http: Http,
        private datePipe: DatePipe,
    ) {
    }
    /**
     * 获得测点快照值
     * 
     * @param {string[]} codes 
     * @returns {(Promise<TagData[]>)} 
     * @memberof HistoryService
     */
    public getSnapshots(codes: string[]): Promise<TagData[]> {
        return this.http.post(`${this.url}/snapshots`, JSON.stringify(codes))
            .toPromise()
            .then(response => {
                try {
                    let result = response.json();
                    switch (result.code) {
                        case "200":
                            return result.data;
                        case "-1":
                            throw new Error(result.message);
                    }
                }
                catch (error) {
                    throw error;
                }
            })
            .catch(this.handleError);
    }


    /**
     * 定时查询测点历史值
     * 
     * @param {number} timerInterval 
     * @param {string[]} codes 
     * @param {Date} time 
     * @returns {Subject<TagData[]>} 
     * @memberof HistoryService
     */
    public getHistoriesWithTimer(timerInterval: number, codes: string[], time: Date): Subject<TagData[]>;
    public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end: Date): Subject<TagData[]>;
    public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end: Date, interval: number): Subject<TagData[]>;
    public getHistoriesWithTimer(timerInterval: number, codes: string[], start: Date, end?: Date, interval?: number): Subject<TagData[]> {
        let subject = new Subject<TagData[]>();
        this.subjectMap.push(subject);
        this.getHistories(codes, start, end, interval)
            .then(res => {
                subject.next(res);
                // 开启定时器
                let timer = setInterval(() => {
                    this.getHistories(codes, start, end, interval)
                        .then(timerRes => {
                            subject.next(timerRes);
                        })
                        .catch(timerError => {
                            subject.error(timerError);
                        });
                }, timerInterval * 1000);
                this.timers.push(timer);
            })
            .catch(error => {
                subject.error(error);
            });
        return subject;
    }

    /**
     * 根据时间点获得历史数据
     * 
     * @param {string[]} codes 测点编码集合
     * @param {Date} time 时间点
     * @returns {(Promise<TagData[]>)} 
     * @memberof HistoryService
     */
    public getHistories(codes: string[], time: Date): Promise<TagData[]>;
    /**
     * 根据时间范围获得历史数据
     * 
     * @param {string[]} codes 测点编码集合
     * @param {Date} start 开始时间
     * @param {Date} end 结束时间
     * @returns {(Promise<TagData[]>)} 
     * @memberof HistoryService
     */
    public getHistories(codes: string[], start: Date, end: Date): Promise<TagData[]>;
    /**
     *  根据时间范围和时间间隔获得历史数据
     * 
     * @param {string[]} codes 测点编码集合
     * @param {Date} start 开始时间
     * @param {Date} end 结束时间
     * @param {number} interval 时间间隔
     * @returns {(Promise<TagData[]>)} 
     * @memberof HistoryService
     */
    public getHistories(codes: string[], start: Date, end: Date, interval: number): Promise<TagData[]>;
    /**
     * 
     * 
     * @param {*} codes 
     * @param {*} start 
     * @param {*} [end] 
     * @param {*} [interval] 
     * @returns {Promise<TagData[]>} 
     * @memberof HistoryService
     */
    public getHistories(codes: any, start: any, end?: any, interval?: any): Promise<TagData[]> {
        let resqustUrl = this.url;
        let startFomat: string = "";
        let endFomat: string = "";

        if (interval != null) {
            if (start == null)
                return Promise.reject("开始时间不能为空！");
            if (end == null)
                return Promise.reject("结束时间不能为空！");
            if (start >= end)
                return Promise.reject("开始时间应该小于结束时间！");
            if (!(interval && interval >= 1))
                return Promise.reject("时间间隔不能为空，并且应该大于等于1秒");

            startFomat = this.datePipe.transform(start, this.fomat);
            endFomat = this.datePipe.transform(end, this.fomat);

            // resqustUrl = `http://192.168.15.150:8585/webapi/v1/historys/startTime/${startFomat}/endTime/${endFomat}/interval/${interval}`
            resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}/interval/${interval}`
        }
        else if (end != null) {
            if (start == null)
                return Promise.reject("开始时间不能为空！");
            if (end == null)
                return Promise.reject("结束时间不能为空！");
            if (start >= end)
                return Promise.reject("开始时间应该小于结束时间！");

            startFomat = this.datePipe.transform(start, this.fomat);
            endFomat = this.datePipe.transform(end, this.fomat);
            // resqustUrl = `http://192.168.15.150:8585/webapi/v1/historys/startTime/${startFomat}/endTime/${endFomat}`;
            resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}`;
        }
        else {
            if (start == null)
                return Promise.reject("时间点不能为空！");

            startFomat = this.datePipe.transform(start, this.fomat);
            //resqustUrl = `http://192.168.15.150:8585/webapi/v1/historys/time/${startFomat}`;
            resqustUrl = `${resqustUrl}/time/${startFomat}`;
        }
        return this.http.post(resqustUrl, JSON.stringify(codes))
            .toPromise()
            .then(response => {
                try {
                    let result = response.json();
                    switch (result.code) {
                        case "200":
                            return result.data as TagData[];
                        case "-1":
                            throw new Error(result.message);
                    }
                }
                catch (error) {
                    throw error;
                }
            })
            .catch(this.handleError);
    }

    /**
     * 获得统计值
     * 
     * @param {string[]} codes 
     * @param {Date} start 
     * @param {Date} end 
     * @returns {(Promise<any> | Observable<any>)} 
     * @memberof HistoryService
     */
    public getSummaries(codes: string[], start: Date, end: Date): Promise<Summary[]>;
    public getSummaries(codes: string[], start: Date, end: Date, interval: number): Promise<Summary[]>;
    public getSummaries(codes: string[], start: Date, end: Date, expr: string): Promise<Summary[]>;
    public getSummaries(codes: any, start: any, end: any, expr?: any): Promise<Summary[]> {
        throw new Error("Method not implemented.");

    }


    /**
     * 根据风机Id，获得时间范围内的该台风机故障信息
     * 
     * @param {number} turbineId 
     * @param {string} alarmCategory 
     * @param {Date} start 
     * @param {Date} end 
     * @param {{ pageIndex: number; eachPage: number; }} [page] 
     * @returns {Promise<FaultPage>} 
     * @memberof HistoryService
     */


    public getTurbineFaults(turbineIds: number[], start: Date, end: Date, alarmCategoryIds?: number[], page?: { pageIndex: number; eachPage: number; }): Promise<FaultData[]> {

        // let resqustUrl = `http://192.168.15.150:8585/webapi/v1/historyAlarms`;
        let resqustUrl = `${AppConfig.APP_RESTFUL}/historyAlarms`;
        let startFomat: string = "";
        let endFomat: string = "";

        if (turbineIds == null)
            return Promise.reject("请选择设备！");
        if (start == null)
            return Promise.reject("开始时间不能为空！");
        if (end == null)
            return Promise.reject("结束时间不能为空！");
        if (start >= end)
            return Promise.reject("开始时间应该小于结束时间！");

        startFomat = this.datePipe.transform(start, this.fomat);
        endFomat = this.datePipe.transform(end, this.fomat);
        resqustUrl = `${resqustUrl}/startTime/${startFomat}/endTime/${endFomat}`;

        return this.http.post(resqustUrl, JSON.stringify(turbineIds))
            .toPromise()
            .then(response => {
                try {
                    let result = response.json();
                    switch (result.code) {
                        case "200":
                            return result.data as FaultData[];
                        case "-1":
                            throw new Error(result.message);
                    }
                }
                catch (error) {
                    throw error;
                }
            })
            .catch(this.handleError);
    }

    public getInverterFaults(deviceIds: number[], start: Date, end: Date, alarmCategoryIds?: number[], page?: { pageIndex: number; eachPage: number; }): Promise<FaultData[]> {

        let resqustUrl = `${AppConfig.APP_RESTFUL}/historyAlarms`;
        let startFomat: string = "";
        let endFomat: string = "";

        if (deviceIds == null)
            return Promise.reject("请选择逆变器！");
        if (start == null)
            return Promise.reject("开始时间不能为空！");
        if (end == null)
            return Promise.reject("结束时间不能为空！");
        if (start >= end)
            return Promise.reject("开始时间应该小于结束时间！");

        startFomat = this.datePipe.transform(start, this.fomat);
        endFomat = this.datePipe.transform(end, this.fomat);
        resqustUrl = `${resqustUrl}/device/startTime/${startFomat}/endTime/${endFomat}`;

        return this.http.post(resqustUrl, JSON.stringify(deviceIds))
            .toPromise()
            .then(response => {
                try {
                    let result = response.json();
                    switch (result.code) {
                        case "200":
                            return result.data as FaultData[];
                        case "-1":
                            throw new Error(result.message);
                    }
                }
                catch (error) {
                    throw error;
                }
            })
            .catch(this.handleError);
    }

    public dispose() {
        this.timers.forEach(timer => {
            clearInterval(timer);
        });
        this.subjectMap.forEach(subject => {
            subject.unsubscribe();
        })
    }
    public getDeviceStatuses(codes: any[], startTime: Date, endTime: Date): Promise<TagData[]> {
        let startFomat = this.datePipe.transform(startTime, this.fomat),
            endFomat = this.datePipe.transform(endTime, this.fomat);
        let resqustUrl = `${this.url}/DistinctHistoryData/startTime/${startFomat}/endTime/${endFomat}`;
        //let resqustUrl = `http://192.168.15.110:8989/webapi/v1/historys/DistinctHistoryData/startTime/${startFomat}/endTime/${endFomat}`;

        return this.http.post(resqustUrl, JSON.stringify(codes))
            .toPromise()
            .then(response => {
                try {
                    let result = response.json();
                    switch (result.code) {
                        case "200":
                            return result.data as TagData[];
                        case "-1":
                            throw new Error(result.message);
                    }
                }
                catch (error) {
                    throw error;
                }
            })
            .catch(this.handleError);
    }
    private handleError(error: any): Promise<any> {
        return Promise.reject(error.message || error);
    }
}

/**
 * 风机故障信息页
 * 
 * @export
 * @interface FaultPage
 */
export interface FaultPage {
    faults: FaultData[];
    page: Page;
}


/**
 * 分页信息
 * 
 * @export
 * @interface Page
 */
export interface Page {
    index: number;
    totle: number;
    each: number;
}
/**
 * 测点统计信息
 * 
 * @export
 * @interface Summary
 */
export interface Summary {
    /**
     * 合计值
     * 
     * @type {number}
     * @memberof Summary
     */
    total: number;
    /**
     * 平均值
     * 
     * @type {number}
     * @memberof Summary
     */
    avg: number;
    /**
     * 最大值
     * 
     * @type null
     * @memberof Summary
     */
    max: number;
    /**
     * 最小值
     * 
     * @type {number}
     * @memberof Summary
     */
    min: number;
    /**
     * 有效值个数
     * 
     * @memberof Summary
     */
    effective: number;
    /**
     * 加权平均值
     * 
     * @memberof Summary
     */
    powerAvg: number;
    /**
     * 批次
     * 
     * @type {number}
     * @memberof Summary
     */
    index: number;
    /**
     * 查询的开始时间 
     * 
     * @type {Date}
     * @memberof Summary
     */
    start: Date;
    /**
     * 查询的结束时间 
     * 
     * @type {Date}
     * @memberof Summary
     */
    end: Date;
    /**
     * 最大值的时间
     * 
     * @type {Date}
     * @memberof Summary
     */
    maxDate: Date;
    /**
     * 最小值的时间
     * 
     * @type {Date}
     * @memberof Summary
     */
    minDate: Date;
}





// WEBPACK FOOTER //
// ./src/app/service/data-source/history.service.ts